package com.softhis.rekrutacja.client.presenter;

import java.util.List;

import com.allen_sauer.gwt.log.client.Log;
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelReader;
import com.extjs.gxt.ui.client.data.ListLoadResult;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import com.mvp4g.client.annotation.Presenter;
import com.mvp4g.client.presenter.BasePresenter;
import com.softhis.rekrutacja.client.MainEventBus;
import com.softhis.rekrutacja.client.view.UserFormView;
import com.softhis.rekrutacja.client.view.UsersModuleView;
import com.softhis.rekrutacja.client.view.widgets.interfaces.IButton;
import com.softhis.rekrutacja.client.view.widgets.interfaces.IGrid;
import com.softhis.rekrutacja.shared.dto.UserDTO;
import com.softhis.rekrutacja.shared.services.UserService.SaveUserCode;
import com.softhis.rekrutacja.shared.services.UserServiceAsync;

@Presenter(view = UsersModuleView.class)
public class UsersModulePresenter extends BasePresenter<UsersModulePresenter.UsersModuleViewInterface, MainEventBus> {


	private ListStore<BeanModel> store = null;
	private ListLoader<ListLoadResult<BeanModel>> loader = null;
	protected int indexSelected = -1;

	@Inject
	private UserServiceAsync userService = null;

	/**
	 * Create a remote user service.
	 */
	public void setUserService(UserServiceAsync userService) {
		this.userService = userService;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public void bind() {

		RpcProxy<List<UserDTO>> proxy = new RpcProxy<List<UserDTO>>() {

			public void load(Object loadConfig, AsyncCallback<List<UserDTO>> callback) {
				userService.getAllUsersList(callback);
			}
		};

		BeanModelReader userDTOReader = new BeanModelReader();
		this.loader = new BaseListLoader<ListLoadResult<BeanModel>>(proxy, userDTOReader);
		this.store = new ListStore<BeanModel>(this.loader);
		view.buildWidget(store);
		
		view.getDeleteButton().addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent event) {
				deleteUser();
			}
		});

		view.getNewButton().addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent event) {
				newUser();
			}
		});
		
		view.getGrid().addListener( Events.RowClick, new Listener<GridEvent>() {

			public void handleEvent( GridEvent be ) {
				selectUser( be.getRowIndex() );			
			}

		} );
		
		view.getUserForm().getSaveButton().addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent event) {
				saveOrUpdate();
			}
		});
		
		view.getUserForm().getCancelButton().setVisible(false);
	}
	
	private void selectUser(int index){
		if ( indexSelected > -1 ) {
			view.getGrid().unSelectRow( indexSelected );
		}
		
		this.indexSelected = index;
		view.getGrid().selectRow( indexSelected );
		view.getUserForm().fillForm((UserDTO)store.getAt( index ).getBean());
		view.getDeleteButton().setEnabled( true );
	}
	
	private void newUser(){
		view.getUserForm().clearForm();
		view.getDeleteButton().setEnabled( false );
		this.indexSelected = -1;
	}
	
	private void deleteUser() {
		UserDTO tempUser = (UserDTO) store.getAt(indexSelected).getBean();
		try {
			userService.deleteUser(tempUser.getUserId(), new AsyncCallback<Void>() {
				public void onFailure(Throwable caught) {
					Log.error("[USER MODULE PRESENTER] delete user fail ", caught);
					MessageBox.alert("Komunikat", "Utracono połącznie z serwerem, spróbuj ponownie później.", null);
				}

				public void onSuccess(Void result) {
					store.remove( store.getAt( indexSelected ) );
					view.getUserForm().clearForm();
					view.getDeleteButton().setEnabled( false );
					indexSelected = -1;
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void saveOrUpdate(){
		
		if(this.indexSelected == -1 ){ //add user
			UserDTO tempUser = view.getUserForm().getUserData();
			try {
				userService.saveUser(tempUser , new AsyncCallback<SaveUserCode>() {
					public void onFailure(Throwable caught) {
						Log.error("[USER MODULE PRESENTER] create new user fail ", caught);
						MessageBox.alert("Komunikat", "Utracono połącznie z serwerem, spróbuj ponownie później.", null);
					}

					public void onSuccess(SaveUserCode result) {
						MessageBox.alert("komunikat", "Dodano nowego użytkownika.", null);
						loader.load();
						view.getDeleteButton().setEnabled( false );
						view.getUserForm().clearForm();
					}
				});
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		else{ // update user
			UserDTO tempGridUser = (UserDTO) store.getAt(indexSelected).getBean();
			UserDTO tempUser = view.getUserForm().getUserData();
			tempUser.setUserId(tempGridUser.getUserId());
			Log.debug("[USER MODULE PRESENTER] update user id " + tempUser.toString());
			
			try {
				userService.updateUser(tempUser , new AsyncCallback<SaveUserCode>() {
					public void onFailure(Throwable caught) {
						Log.error("[USER MODULE PRESENTER] update user fail ", caught);
						MessageBox.alert("Komunikat", "Utracono połącznie z serwerem, spróbuj ponownie później.", null);
					}

					public void onSuccess(SaveUserCode result) {
						loader.load();
						indexSelected = -1;
						view.getUserForm().clearForm();
						view.getDeleteButton().setEnabled( false );
					}
				});
			} catch (Exception e) {
				Log.error("[USER MODULE PRESENTER] update user  try catch ", e);
			}
		}
	}

	public void onOpenUsersModule() {
		loader.load();
		eventBus.setContent((Widget) view);
	}

	public interface UsersModuleViewInterface {

		void buildWidget(ListStore<BeanModel> store);

		public IGrid getGrid();

		public IButton getDeleteButton();

		public IButton getNewButton();

		public UserFormView getUserForm();
	}
}
